package com.fas.core.plugin.shiro.matcher;

import java.util.concurrent.atomic.AtomicInteger;

import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.cache.Cache;
import org.apache.shiro.cache.CacheManager;

/**
 * 登录失败次数限制
 *
 * @Copyright: Copyright (c) 2016 FAS
 * @anthor yixiaoping<thinker1013@163.com>
 * @since 2016年1月24日 下午10:14:19
 * @version V1.0
 */
public class RetryLimitHashedCredentialsMatcher extends HashedCredentialsMatcher {

	private Cache<String, AtomicInteger> passwordRetryCache;
	private CacheManager cacheManager;

	public CacheManager getCacheManager() {
		return cacheManager;
	}

	public void setCacheManager(CacheManager cacheManager) {
		this.cacheManager = cacheManager;
		passwordRetryCache = cacheManager.getCache("passwordRetryCache");
	}

	public RetryLimitHashedCredentialsMatcher() {
		super();
		// TODO Auto-generated constructor stub
	}

	public RetryLimitHashedCredentialsMatcher(String hashAlgorithmName) {
		super(hashAlgorithmName);
		// TODO Auto-generated constructor stub
	}

	public RetryLimitHashedCredentialsMatcher(CacheManager cacheManager) {
		cacheManager = this.cacheManager;
	}

	@Override
	public boolean doCredentialsMatch(AuthenticationToken token, AuthenticationInfo info) {
		String username = (String) token.getPrincipal();
		// retry count + 1
		AtomicInteger retryCount = passwordRetryCache.get(username);
		if (retryCount == null) {
			retryCount = new AtomicInteger(0);
			passwordRetryCache.put(username, retryCount);
		}
		if (retryCount.incrementAndGet() > 5) {
			// if retry count > 5 throw
			throw new ExcessiveAttemptsException("错误尝试5次，帐号将锁定10分钟。");
		}

		boolean matches = super.doCredentialsMatch(token, info);
		if (matches) {
			// clear retry count
			passwordRetryCache.remove(username);
		}
		return matches;
	}
}
